package com.wgchao.amc.service.impl;

import com.wgchao.amc.common.EvaluateInfo;
import com.wgchao.amc.common.ResultCommon;
import com.wgchao.amc.entity.autho.SysAuthoRole;
import com.wgchao.amc.entity.autho.SysAuthoRoleFunc;
import com.wgchao.amc.entity.base.*;
import com.wgchao.amc.entity.menu.SysMenuProject;
import com.wgchao.amc.mapstruct.dto.SysAuthoRoleDTO;
import com.wgchao.amc.mapstruct.dto.SysAuthoRoleFuncDTO;
import com.wgchao.amc.mapstruct.mapper.SysAuthoGroupFuncMapper;
import com.wgchao.amc.mapstruct.mapper.SysAuthoRoleFuncMapper;
import com.wgchao.amc.mapstruct.mapper.expand.SysAuthoRoleMapperExpand;
import com.wgchao.amc.repository.autho.SysAuthoRoleFuncRepository;
import com.wgchao.amc.repository.autho.SysAuthoRoleRepository;
import com.wgchao.amc.repository.base.*;
import com.wgchao.amc.repository.menu.SysMenuProjectRepository;
import com.wgchao.amc.service.EvaluateService;
import com.wgchao.amc.service.RoleAuthoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @ClassName: RoleAuthoServiceImpl
 * @author: wgchao
 * @createTime: 2019/10/31 10:17 AM
 * @Description: 部门角色权限管理
 */
@Service
@Transactional
public class RoleAuthoServiceImpl implements RoleAuthoService, EvaluateService {
    @Autowired
    private SysBaseGroupRepository groupRepository;
    @Autowired
    private SysMenuProjectRepository projectRepository;
    @Autowired
    private SysBaseMenuRepository menuRepository;
    @Autowired
    private SysBaseFuncRepository funcRepository;
    @Autowired
    private SysBaseRoleRepository roleRepository;
    @Autowired
    private SysBaseGrRepository grRepository;
    @Autowired
    private SysAuthoRoleRepository authoRoleRepository;
    @Autowired
    private SysAuthoRoleFuncRepository authoRoleFuncRepository;
    @Autowired
    private SysAuthoRoleMapperExpand authoRoleMapperExpand;
    @Autowired
    private SysAuthoRoleFuncMapper authoRoleFuncMapper;

    /**
     * 为部门角色分配菜单权限
     * @param groupId 部门ID
     * @param roleId 角色ID
     * @param proMark 项目标示
     * @param authoRoleDTOS 菜单权限信息
     * @return
     * @throws Exception
     */
    @Override
    public ResultCommon<List<SysAuthoRoleDTO>> assign(Long groupId, Long roleId, String proMark, List<SysAuthoRoleDTO> authoRoleDTOS) throws Exception {
        //数据检校
        EvaluateInfo evaluateInfo = evaluate(authoRoleDTOS, gads -> {
            List<SysAuthoRoleDTO> gaDtos = (List<SysAuthoRoleDTO>) gads;
            Optional<SysBaseGroup> groupOptional = groupRepository.findById(groupId);
            if(!groupOptional.isPresent()){
                return new EvaluateInfo(false, "部门不存在");
            }
            SysBaseGroup group = groupOptional.get();
            if(group.isDel()){
                return new EvaluateInfo(false, "部门已删除");
            }
            SysMenuProject project = projectRepository.findFirstByProMark(proMark);
            if(project == null){
                return new EvaluateInfo(false, "项目不存在");
            }

            Optional<SysBaseRole> roleOptional = roleRepository.findById(roleId);
            if(!roleOptional.isPresent()){
                return new EvaluateInfo(false, "角色不存在");
            }
            SysBaseRole role = roleOptional.get();
            if(role.isDel()){
                return new EvaluateInfo(false, "角色已删除");
            }

            SysBaseGr gr = grRepository.findFirstByRoleIdAndGroupId(roleId, groupId);
            if(gr == null){
                return new EvaluateInfo(false, "角色不属于该部门");
            }

            for(SysAuthoRoleDTO roleDTO:gaDtos){
                Optional<SysBaseMenu> menuOptional = menuRepository.findById(roleDTO.getMenuId());
                if(!menuOptional.isPresent()){
                    return new EvaluateInfo(false, roleDTO.getMenuId()+"菜单不存在");
                }
                SysBaseMenu menu = menuOptional.get();
                if(!menu.getProMark().equals(proMark)){
                    return new EvaluateInfo(false, menu.getMenuName()+"菜单不再该项目中");
                }
                List<SysAuthoRoleFuncDTO> roleFuncs = roleDTO.getFuncInfos();
                if(roleFuncs!=null && !roleFuncs.isEmpty() ){
                    for(SysAuthoRoleFuncDTO funcDTO:roleFuncs){
                        Optional<SysBaseFunc> funcOptional = funcRepository.findById(funcDTO.getFuncId());
                        if(!funcOptional.isPresent()){
                            return new EvaluateInfo(false, funcDTO.getFuncId()+"功能操作不存在");
                        }
                    }
                }
            }
            return new EvaluateInfo(true, null);
        });
        if(!evaluateInfo.isSuccess()){
            return ResultCommon.fail(evaluateInfo.getMsg());
        }

        //删除原有的菜单权限
        List<SysAuthoRole> oldRas = authoRoleRepository.findAllByGroupIdAndRoleIdAndProMarkOrderById(groupId, roleId, proMark);
        if(oldRas!=null && !oldRas.isEmpty()){
            for(SysAuthoRole oldRa:oldRas){
                List<SysAuthoRoleFunc> rafuncs = authoRoleFuncRepository.findAllByArId(oldRa.getId());
                if(rafuncs!=null && !rafuncs.isEmpty()){
                    authoRoleFuncRepository.deleteAll(rafuncs);
                }
            }
            authoRoleRepository.deleteAll(oldRas);
        }

        //设置新的菜单权限信息
        for(SysAuthoRoleDTO authoRoleDTO:authoRoleDTOS){
            SysAuthoRole authoRole = authoRoleMapperExpand.toEntity(authoRoleDTO);
            authoRole.setGroupId(groupId);
            authoRole.setRoleId(roleId);
            authoRole.setProMark(proMark);
            authoRole.setCreateTime(new Date());
            authoRole = authoRoleRepository.save(authoRole);

            List<SysAuthoRoleFuncDTO> roleFuncs = authoRoleDTO.getFuncInfos();
            if(roleFuncs!=null && !roleFuncs.isEmpty() ){
                //保存菜单功能信息
                for(SysAuthoRoleFuncDTO funcDTO:roleFuncs){
                    SysAuthoRoleFunc authoGroupFunc = authoRoleFuncMapper.toEntity(funcDTO);
                    authoGroupFunc.setArId(authoRole.getId());
                    authoGroupFunc = authoRoleFuncRepository.save(authoGroupFunc);
                }
            }
        }

        List<SysAuthoRole> authoRoles = authoRoleRepository.findAllByGroupIdAndRoleIdAndProMarkOrderById(groupId, roleId, proMark);
        authoRoleDTOS = authoRoles.stream().map(sysAuthoGroup -> {
            SysAuthoRoleDTO authoRoleDTO = authoRoleMapperExpand.toDTO(sysAuthoGroup);
            authoRoleDTO = authoRoleMapperExpand.getFuncInfo(authoRoleDTO);
            return authoRoleDTO;
        }).collect(Collectors.toList());
        return ResultCommon.success().setData(authoRoleDTOS);
    }

    /**
     * 查询部门角色菜单权限
     * @param groupId 部门ID
     * @param roleId 角色ID
     * @param proMark 项目标示
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(readOnly = true)
    public ResultCommon<List<SysAuthoRoleDTO>> search(Long groupId, Long roleId, String proMark) throws Exception {
        List<SysAuthoRole> authoRoles = authoRoleRepository.findAllByGroupIdAndRoleIdAndProMarkOrderById(groupId, roleId, proMark);
        List<SysAuthoRoleDTO> authoRoleDTOS = authoRoles.stream().map(sysAuthoGroup -> {
            SysAuthoRoleDTO authoRoleDTO = authoRoleMapperExpand.toDTO(sysAuthoGroup);
            authoRoleDTO = authoRoleMapperExpand.getFuncInfo(authoRoleDTO);
            return authoRoleDTO;
        }).collect(Collectors.toList());
        return ResultCommon.success().setData(authoRoleDTOS);
    }
}
